package com.sbtr.controller;

import com.sbtr.business.project.service.IProjectService;
import com.sbtr.business.trainingmodel.entity.TrainingModelData;
import com.sbtr.business.trainingmodel.service.ITrainingModelDataService;
import com.sbtr.common.Response;
import com.sbtr.constant.ProjectConstant;
import com.sbtr.open.importmodel.dto.ImportModelTaskDto;
import com.sbtr.open.project.dto.ProjectDto;
import com.sbtr.open.trainingmodel.dto.TrainingModelDataDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.UUID;

@RestController
@RequestMapping("/import-model-task")
@Api(tags = "模型导入模块（仅仅包括sklearn模型，暂时不启用）")
public class ImportModelTaskController {

//	@Autowired
//	private IImportModelTaskApi importTaskApi;

	@Autowired
	private IProjectService projectService;

	@Autowired
	private ITrainingModelDataService trainingModelDataService;

	@Value("${oss.config.uploadPath}")
	private String uploadPath;


	@Value("${oss.config.samplePath}")
	private String samplePath;

	@ApiOperation(value = "保存模型导入任务", notes = "保存模型导入任务", httpMethod = "POST")
	@RequestMapping(value = "/save", method = RequestMethod.POST , headers = "content-type=multipart/form-data")
	public Response<TrainingModelDataDto> save(@RequestPart(value = "File") MultipartFile file, ImportModelTaskDto dto) {

		if (file.isEmpty() || file.getSize() == 0) {
			throw new IllegalArgumentException("上传文件为空！！");
		}

		Date now = new Date();
		//1.新增项目
		ProjectDto projectDto = new ProjectDto();
		projectDto.setProjectName(dto.getName());
		projectDto.setProjectDesc(dto.getDescr());
		projectDto.setProjectType(dto.getProjectType());
		projectDto.setCreateTime(now);
		projectDto.setCreater(dto.getCreator());
		projectDto.setModelFileType(dto.getModelFileType());
		projectDto.setStatus(ProjectConstant.PROJECT_STATUS_UNPUBLISH);
		projectDto.setProgressRate(ProjectConstant.PROJECT_PROGRESS_LOAD);
		projectDto = projectService.save(projectDto);



		//2.新增模型记录
		TrainingModelDataDto model = new TrainingModelDataDto();
		model.setProjectId(projectDto.getId());//关联项目
		model.setType(dto.getProjectType());
		model.setProjectName(dto.getName());
		model.setCreater(dto.getCreator());
		model.setCreateTime(now);
		model.setModelName(dto.getName());
		model.setModelFileType(dto.getModelFileType());//sklearn；matlab
		model.setIsExternalImport(2);//外部导入模型
		model.setStatus("unpublish");//未发布
		model = trainingModelDataService.save(model);

		//保存模型文件
		String fileName = file.getOriginalFilename();//源文件名
		//防止上传重复文件报错，用UUID生成新的文件名
		String otherName = UUID.randomUUID().toString().replaceAll("-", "")
				+ fileName.substring(fileName.lastIndexOf("."));

		String bucketDir = uploadPath + File.separator + "importModel";
		String filePath = bucketDir + File.separator + otherName;

		OutputStream os = null;
		InputStream inputStream = null;
		try {
			inputStream = file.getInputStream();
			// 2、保存到临时文件
			// 1K的数据缓冲
			byte[] bs = new byte[1024];
			// 读取到的数据长度
			int len;
			// 输出的文件流保存到本地文件
			File tempFile = new File(bucketDir);
			boolean results = tempFile.mkdirs();
			if (!tempFile.exists()) {
				tempFile.mkdirs();
			}
			os = new FileOutputStream(filePath);
			// 开始读取
			while ((len = inputStream.read(bs)) != -1) {
				os.write(bs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 完毕，关闭所有链接
			try {
				os.close();
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		//logger.info("上传外部模型成功,路径：{}",filePath);
		//更新task 路径：
		model.setModelDir(filePath);

		return Response.success(trainingModelDataService.save(model));
	}

	@ApiOperation(value = "下载模型模板", notes = "下载模型模板", httpMethod = "POST")
	@RequestMapping(value = "/downloadModelTemplate", method = RequestMethod.POST)
	@ResponseBody
	public void downloadModelTemplate(@RequestParam String projectType, HttpServletResponse resp){

		String filePath = null;
		if (projectType.equals("sklearn")) {
			filePath = samplePath+"/sklearn_ImportDemo.zip";

		}else if(projectType.equals("matlab")){
			filePath = samplePath+"/matlab_ImportDemo.zip";

		}else {
			throw new IllegalArgumentException("projectType 参数异常:"+projectType);
		}

		OutputStream out;
		// 读取本地文件的输入流
		InputStream in;
		File file = new File(filePath);
		//下载
		try {
			in = new FileInputStream(file);
			// 设置响应正文的MIME类型
			//resp.setContentType( "application/octet-stream");
//			resp.setContentType("Content-Disposition;charset=UTF-8");
			resp.setContentType("application/octet-stream");
			resp.setHeader("Content-Disposition", "attachment;" + " filename=" + file.getName());
			// 把本地文件发送给客户端
			out = resp.getOutputStream();
			int byteRead = 0;
			byte[] buffer = new byte[512];
			while ((byteRead = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteRead);
			}
			in.close();
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}


/*	@ApiOperation(value = "删除模型导入任务", notes = "删除模型导入任务", httpMethod = "POST")
	@PostMapping(value = "/delete")
	public Response<Boolean> delete(@RequestParam("id") int id){

		return Response.success(importTaskApi.delete(id));
	}

	@ApiOperation(value = "批量删除", notes = "批量删除模型", httpMethod = "POST")
	@PostMapping(value = "/batchDelete")
	public Response<Integer> batchDelete(@RequestBody List<Long> idList) {

		return Response.success(importTaskApi.batchDelete(idList));
	}

	@ApiOperation(value = "获取导入模型列表", notes = "获取			预测列表", httpMethod = "POST")
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public Response<PageDto<ImportModelTaskDto>> search(@RequestBody ImportModelTaskSearchDto dto) {
		return Response.success(importTaskApi.search(dto));
	}

	@ApiOperation(value = "模型导入的模型上传", notes = "模型导入的模型上传", httpMethod = "POST")
	@RequestMapping(value = "/upload/{id}", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
	public Response<ImportModelTaskDto> upload(
			@PathVariable("id") Long id,//任务id
			@RequestParam(value = "File") MultipartFile file){

			if (file.isEmpty() || file.getSize() == 0) {
				return null;
			}
			try {
				ImportModelTaskDto task = importTaskApi.getById(String.valueOf(id));
				String fileName = file.getOriginalFilename();//源文件名
				//防止上传重复文件报错，用UUID生成新的文件名
				String otherName = UUID.randomUUID().toString().replaceAll("-", "")
						+ fileName.substring(fileName.lastIndexOf("."));

				String bucketDir = uploadPath + File.separator + "importModel";
				String filePath = bucketDir + File.separator + otherName;

				OutputStream os = null;
				InputStream inputStream = null;
				try {
					inputStream = file.getInputStream();
					// 2、保存到临时文件
					// 1K的数据缓冲
					byte[] bs = new byte[1024];
					// 读取到的数据长度
					int len;
					// 输出的文件流保存到本地文件
					File tempFile = new File(bucketDir);
					boolean results = tempFile.mkdirs();
					if (!tempFile.exists()) {
						tempFile.mkdirs();
					}
					os = new FileOutputStream(filePath);
					// 开始读取
					while ((len = inputStream.read(bs)) != -1) {
						os.write(bs, 0, len);
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					// 完毕，关闭所有链接
					try {
						os.close();
						inputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

				//logger.info("上传外部模型成功,路径：{}",filePath);
				//更新task 路径：
				task.setFilePath(filePath);
				importTaskApi.save(task);
				return Response.success(task);
			} catch (Exception e) {
				e.printStackTrace();
				return Response.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "上传失败");
			}

	}

	*//**
	 * 下线外部模型:
	 * 发送请求到python端
	 * @param req
	 * @return
	 *//*
	@ApiOperation(value = "下线外部模型", notes = "下线外部模型", httpMethod = "POST")
	@RequestMapping(value = "/offlineExternalModel", method = RequestMethod.POST)
	@ResponseBody
	public Response<String> offlineExternalModel(@RequestBody PublishTaskDataReqDto req) {

		return importTaskApi.offlineExternalModel(req);
	}

	*//**
	 * 发布外部模型:
	 * 发送请求到python端
	 * @param req
	 * @return
	 *//*
	@ApiOperation(value = "发布外部模型", notes = "发布外部模型，必须是真实模型文件", httpMethod = "POST")
	@RequestMapping(value = "/publishExternalModel", method = RequestMethod.POST)
	@ResponseBody
	public Response<String> publishExternalModel(@RequestBody PublishTaskDataReqDto req) {

		return importTaskApi.publishExternalModel(req);
	}*/


	/**
	 * 导入模型的[测试按钮]，生成 预测任务
	 * @param id
	 * @return
	 */
/*	@ApiOperation(value = "预测", notes = "保存预测的数据文件，生成预测任务", httpMethod = "POST")
	@RequestMapping(value = "/{id}/import-model-predict", method = RequestMethod.POST , headers = "content-type=multipart/form-data")
	public Response<PublishPredictTaskDto> predictDataMultiCreate(@PathVariable("id") Long id, @RequestParam(value = "File") MultipartFile file,
																							   @RequestParam("creater") String creater){
		String fileName = file.getOriginalFilename();//req.getFileOssName();
//
//        String bucketName=req.getBucketDir();
		// 先处理上传的文件
		if (!fileName.toLowerCase().endsWith(".xls") && !fileName.toLowerCase().endsWith(".xlsx")
				&& !fileName.toLowerCase().endsWith(".txt") && !fileName.toLowerCase().endsWith(".csv")
				&& !fileName.toLowerCase().endsWith(".zip")) {
			//logger.error(fileName + " 上传文件不是excel,csv,txt,zip");
			throw new RuntimeException(fileName + " 上传文件不是excel,csv,txt,zip");
		}

		*//** 生成我的预测任务，跟踪预测流程 **//*
		String predictFilePath = this.saveTestFile(file,id);//保存文件

		return Response.success(importTaskApi.predictDataMultiCreate(id, predictFilePath, creater));
	}*/

	//	保存上传的测试文件
	public String saveTestFile(MultipartFile file,Long  taskId) {

		String fileName = file.getOriginalFilename();//源文件名
		//防止上传重复文件报错，用UUID生成新的文件名
		String otherName = UUID.randomUUID().toString().replaceAll("-", "")
				+ fileName.substring(fileName.lastIndexOf("."));

		String bucketDir = uploadPath + File.separator + "importModelTest" + File.separator + taskId ;

		OutputStream os = null;
		InputStream inputStream = null;
		try {
			inputStream = file.getInputStream();
			// 2、保存到临时文件
			// 1K的数据缓冲
			byte[] bs = new byte[1024];
			// 读取到的数据长度
			int len;
			// 输出的文件流保存到本地文件
			File tempFile = new File(bucketDir);
			boolean results = tempFile.mkdirs();
			if (!tempFile.exists()) {
				tempFile.mkdirs();
			}
			os = new FileOutputStream(tempFile.getPath() + File.separator + otherName);
			// 开始读取
			while ((len = inputStream.read(bs)) != -1) {
				os.write(bs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 完毕，关闭所有链接
			try {
				os.close();
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bucketDir + File.separator + otherName;
	}
}
